import java.util.Random;

/**
 * 两种写法比较ThreadLocal的应用
 */
public class ThreadLocalTest {

	//蹩脚写法演示:把数据直接写到ThreadLocal中，使用的时候要new一个然后set
//	private static ThreadLocal<ThreadLocalData> data = new ThreadLocal<ThreadLocalData>();
	
	public static void main(String[] args) {
		for(int i=0;i<2;i++){
			new Thread(new Runnable(){
				public void run() {
					int no = new Random().nextInt();
//					ThreadLocalData threadLocalData = new ThreadLocalData();
//					threadLocalData.setAge(no);
//					threadLocalData.setName(Thread.currentThread().getName()+no);
//					data.set(threadLocalData);
					ThreadLocalData.getInstance().setAge(no);
					ThreadLocalData.getInstance().setName(Thread.currentThread().getName()+no);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A {
		public void get() {
			System.out.println("A : "+ThreadLocalData.getInstance().getName()+","+ThreadLocalData.getInstance().getAge());
		}
	}
	
	static class B {
		public void get() {
			System.out.println("B : "+ThreadLocalData.getInstance().getName()+","+ThreadLocalData.getInstance().getAge());
		}
	}
}


class ThreadLocalData {
	
//	private static ThreadLocalData instance = null ;//new ThreadLocalData(); //饱汉写法
	//每个线程一个实例用ThreadLocal实现
	private static ThreadLocal<ThreadLocalData> data = new ThreadLocal<ThreadLocalData>();
	
	public static /*synchronized
				   *  这种写法保证单例模式下的线程安全，在ThreadLocal线程共享下是不是必要的
	               */ ThreadLocalData getInstance() {
		if(data.get() == null)
			data.set(new ThreadLocalData());
		return data.get();
	}
	
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}
